/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

package xowl.interpreter.backends.rdf;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import xowl.interpreter.backends.rete.Condition;
import xowl.interpreter.backends.rete.RETERule;
import xowl.interpreter.backends.rete.Token;
import xowl.interpreter.backends.rete.TokenActivable;
import xowl.interpreter.frontends.VocRDF;

/**
 *
 * @author Laurent WOUTERS
 */
public class TranslatorRDF_OWL2 {
    private RDFRepository repository;
    private Map<String, java.lang.Class> mapTypes;

    public TranslatorRDF_OWL2(RDFRepository repository) {
        this.repository = repository;
        this.mapTypes = new HashMap<String, java.lang.Class>();
        this.mapTypes.put(VocRDF.owlClass, xowl.lang.runtime.Class.class);
        this.mapTypes.put(VocRDF.rdfsDatatype, xowl.lang.runtime.Datatype.class);
        this.mapTypes.put(VocRDF.owlObjectProperty, xowl.lang.runtime.ObjectProperty.class);
        this.mapTypes.put(VocRDF.owlDataProperty, xowl.lang.runtime.DataProperty.class);
        this.mapTypes.put(VocRDF.owlAnnotationProperty, xowl.lang.runtime.AnnotationProperty.class);
        this.mapTypes.put(VocRDF.owlNamedIndividual, xowl.lang.runtime.NamedIndividual.class);
    }
    
    public List<xowl.lang.owl2.Axiom> translateOntology(xowl.interpreter.impl.AggregatedEvaluator evaluator, RDFGraph graph, xowl.lang.owl2.Ontology ontology) {
        Job job = new Job(true, evaluator);
        return job.execute(graph, ontology);
    }
    
    protected static class Trigger {
        public TranslatorRDF_Rule rule;
        public Map<XOWLVariableNode, RDFNode> bindings;
        public Trigger(TranslatorRDF_Rule rule, Map<XOWLVariableNode, RDFNode> bindings) {
            this.rule = rule;
            this.bindings = bindings;
        }
        public void execute() { rule.activate(bindings); }
    }
    
    protected class Job {
        protected boolean translateAnnotations;
        protected xowl.interpreter.impl.AggregatedEvaluator evaluator;
        protected xowl.interpreter.backends.rete.RETENetwork network;
        protected List<Trigger> activations;
        protected RDFGraph graph;
        protected xowl.lang.owl2.Ontology ontology;
        protected List<xowl.lang.owl2.Axiom> axioms;
        protected Map<RDFNode, ExpressionSolver> expDatarange;
        protected Map<RDFNode, ExpressionSolver> expClasses;
        protected Map<RDFNode, ExpressionSolver> expObjProperties;
        protected List<RETERule> bufferRules;
        
        protected abstract class ExpressionSolver {
            public abstract xowl.lang.owl2.Expression getExpression();
        }
        
        public Job(boolean translateAnnotations, xowl.interpreter.impl.AggregatedEvaluator evaluator) {
            super();
            this.translateAnnotations = translateAnnotations;
            this.evaluator = evaluator;
            this.network = new xowl.interpreter.backends.rete.RETENetwork();
        }
        
        public List<xowl.lang.owl2.Axiom> execute(RDFGraph graph, xowl.lang.owl2.Ontology ontology) {
            this.activations = new ArrayList<Trigger>();
            this.graph = graph;
            this.ontology = ontology;
            buildRules();
            Iterator<RDFTriple> iter;
            if (ontology != null)
                iter = this.graph.getIterator(ontology);
            else
                iter = this.graph.getIterator();
            while (iter.hasNext())
                network.inject(new RDFChange(iter.next(), ontology, true));
            this.axioms = new ArrayList<xowl.lang.owl2.Axiom>();
            this.expDatarange = new HashMap<RDFNode, ExpressionSolver>();
            this.expClasses = new HashMap<RDFNode, ExpressionSolver>();
            this.expObjProperties = new HashMap<RDFNode, ExpressionSolver>();
            
            java.util.Collections.sort(activations, new java.util.Comparator<Trigger>() {
                @Override public int compare(Trigger t1, Trigger t2) {
                    return t1.rule.getPriority() - t2.rule.getPriority();
                }
            });
            for (Trigger trigger : activations)
                trigger.execute();
            return axioms;
        }
        
        protected void addRule(final TranslatorRDF_Rule rule) {
            RETERule reteRule = new RETERule(new TokenActivable() {
                @Override public void activateToken(Token token) {
                    activations.add(new Trigger(rule, token.getBindings()));
                }
                @Override public void deactivateToken(Token token) { }
                @Override public void activateTokens(Collection<Token> tokens) {
                    for (Token token : tokens)
                        activateToken(token);
                }
                @Override public void deactivateTokens(Collection<Token> tokens) { }
            });
            for (int i=0; i!=rule.getPatterns().length; i++)
                reteRule.getPositives().add(new Condition(null, rule.getPatterns()[i]));
            bufferRules.add(reteRule);
        }
        
        protected RDFTriple getTriple(RDFSubjectNode subject, RDFProperty property, RDFNode object) { return new RDFTriple(subject, property, object); }
        protected RDFTriple getTriple(RDFSubjectNode subject, String property, RDFNode object) { return new RDFTriple(subject, graph.getEntityNode(repository.getIRI(property)), object); }
        protected RDFTriple getTriple(RDFSubjectNode subject, String property, String object) { return new RDFTriple(subject, graph.getEntityNode(repository.getIRI(property)), graph.getEntityNode(repository.getIRI(object))); }
        
        protected xowl.lang.owl2.DatarangeSequence getDatarangeSequence(List<RDFNode> elems) {
            xowl.lang.owl2.DatarangeSequence seq = new xowl.lang.owl2.DatarangeSequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.DatarangeElement ce = new xowl.lang.owl2.DatarangeElement();
                ce.setIndex(i);
                ce.setDatarange(getDatarange(elem));
                seq.addDatarangeElements(ce);
            }
            return seq;
        }
        protected xowl.lang.owl2.ClassSequence getClassSequence(List<RDFNode> elems) {
            xowl.lang.owl2.ClassSequence seq = new xowl.lang.owl2.ClassSequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.ClassElement ce = new xowl.lang.owl2.ClassElement();
                ce.setIndex(i);
                ce.setClasse(getClassExpression(elem));
                seq.addClassElements(ce);
            }
            return seq;
        }
        protected xowl.lang.owl2.DataPropertySequence getDataPropSequence(List<RDFNode> elems) {
            xowl.lang.owl2.DataPropertySequence seq = new xowl.lang.owl2.DataPropertySequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.DataPropertyElement ce = new xowl.lang.owl2.DataPropertyElement();
                ce.setIndex(i);
                ce.setDataProperty(getDataPropExpression(elem));
                seq.addDataPropertyElements(ce);
            }
            return seq;
        }
        protected xowl.lang.owl2.ObjectPropertySequence getObjPropSequence(List<RDFNode> elems) {
            xowl.lang.owl2.ObjectPropertySequence seq = new xowl.lang.owl2.ObjectPropertySequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.ObjectPropertyElement ce = new xowl.lang.owl2.ObjectPropertyElement();
                ce.setIndex(i);
                ce.setObjectProperty(getObjPropExpression(elem));
                seq.addObjectPropertyElements(ce);
            }
            return seq;
        }
        protected xowl.lang.owl2.LiteralSequence getLiteralSequence(List<RDFNode> elems) {
            xowl.lang.owl2.LiteralSequence seq = new xowl.lang.owl2.LiteralSequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.LiteralElement ce = new xowl.lang.owl2.LiteralElement();
                ce.setIndex(i);
                ce.setLiteral(getLiteralExpression(elem));
                seq.addLiteralElements(ce);
            }
            return seq;
        }
        protected xowl.lang.owl2.IndividualSequence getIndividualSequence(List<RDFNode> elems) {
            xowl.lang.owl2.IndividualSequence seq = new xowl.lang.owl2.IndividualSequence();
            int i=0;
            for (RDFNode elem : elems) {
                xowl.lang.owl2.IndividualElement ce = new xowl.lang.owl2.IndividualElement();
                ce.setIndex(i);
                ce.setIndividual(getIndividualExpression(elem));
                seq.addIndividualElements(ce);
            }
            return seq;
        }
        
        
        protected xowl.lang.owl2.Datarange getDatarange(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            return (xowl.lang.owl2.Datarange)expDatarange.get(node).getExpression();
        }
        protected xowl.lang.owl2.ClassExpression getClassExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            return (xowl.lang.owl2.ClassExpression)expClasses.get(node).getExpression();
        }
        protected xowl.lang.owl2.ObjectPropertyExpression getObjPropExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            return (xowl.lang.owl2.ObjectPropertyExpression)expObjProperties.get(node).getExpression();
        }
        protected xowl.lang.owl2.IRI getAnnotPropExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            return null;
        }
        protected xowl.lang.owl2.DataPropertyExpression getDataPropExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            return null;
        }
        protected xowl.lang.owl2.LiteralExpression getLiteralExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.Literal)
                return xowl.utils.Values.getExpression(((RDFLiteralNode)node).getLiteral());
            return null;
        }
        protected xowl.lang.owl2.IndividualExpression getIndividualExpression(RDFNode node) {
            if (node.getNodeType() == RDFNodeType.IRIReference)
                return ((RDFIRIReference)node).getIRI();
            else if (node.getNodeType() == RDFNodeType.Anonymous)
                return ((RDFBlankNode)node).getOWLIndividual();
            return null;
        }
        
        
        private void buildRules() {
            bufferRules = new ArrayList<RETERule>();
            buildInfInverseOf();
            buildInfClass();
            
            buildObjPropExp_InverseOf();
            
            buildDatarange_Intersection();
            buildDatarange_Union();
            buildDatarange_Complement();
            buildDatarange_OneOf();
            buildDatarange_Restriction();
            
            buildClassExp_Intersection();
            buildClassExp_Union();
            buildClassExp_ComplementOf();
            buildClassExp_OneOf();
            buildClassExp_ObjAllValuesFrom();
            buildClassExp_ObjSomeValuesFrom();
            buildClassExp_ObjHasValue();
            buildClassExp_ObjHasSelf();
            buildClassExp_ObjMinQualifiedCard();
            buildClassExp_ObjMaxQualifiedCard();
            buildClassExp_ObjExactQualifiedCard();
            buildClassExp_ObjMinCard();
            buildClassExp_ObjMaxCard();
            buildClassExp_ObjExactCard();
            buildClassExp_DataHasValue();
            buildClassExp_DataAllValuesFrom();
            buildClassExp_DataSomeValuesFrom();
            buildClassExp_DataAllValuesFrom2();
            buildClassExp_DataSomeValuesFrom2();
            buildClassExp_DataMinQualifiedCard();
            buildClassExp_DataMaxQualifiedCard();
            buildClassExp_DataExactQualifiedCard();
            buildClassExp_DataMinCard();
            buildClassExp_DataMaxCard();
            buildClassExp_DataExactCard();
            
            buildAxiomSubClassOf();
            buildAxiomEquivalentClass();
            buildAxiomDisjointClasses();
            buildAxiomAllDisjointClasses();
            buildAxiomDisjointUnionOf();
            buildAxiomSubObjPropertyOf();
            buildAxiomSubObjPropertyOf_Chain();
            buildAxiomEquivalentObjProp();
            buildAxiomDisjointObjProp();
            buildAxiomAllDisjointObjProps();
            buildAxiomObjPropDomain();
            buildAxiomObjPropRange();
            buildAxiomInverseOf();
            buildAxiomFunctionalObjectProperty();
            buildAxiomInverseFunctionalProperty();
            buildAxiomReflexiveProperty();
            buildAxiomIrreflexiveProperty();
            buildAxiomSymmetricProperty();
            buildAxiomAsymmetricProperty();
            buildAxiomTransitiveProperty();
            buildAxiomSubDataPropertyOf();
            buildAxiomEquivalentDataProp();
            buildAxiomDisjointDataProp();
            buildAxiomAllDisjointDataProps();
            buildAxiomDataPropDomain();
            buildAxiomDataPropRange();
            buildAxiomFunctionalDataProperty();
            buildAxiomEquivalentDatatype();
            buildAxiomHasKey();
            buildAxiomSameAs();
            buildAxiomDifferentFrom();
            buildAxiomAllDifferent();
            buildAxiomClassAssertion();
            buildAxiomObjectPropertyAssertion();
            buildAxiomDataPropertyAssertion();
            buildAxiomNegativeObjectPropertyAssertion();
            buildAxiomNegativeDataPropertyAssertion();
            buildAxiomSubAnnotPropertyOf();
            buildAxiomAnnotPropDomain();
            buildAxiomAnnotPropRange();
            network.addRules(bufferRules);
        }
        
        
        private void buildInfInverseOf() {
            addRule(new TranslatorRDF_Rule(0) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlInverseOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    RDFProperty prop = graph.getEntityNode(repository.getIRI(VocRDF.rdfType));
                    RDFNode type = graph.getEntityNode(repository.getIRI(VocRDF.owlObjectProperty));
                    graph.onChange(evaluator, new RDFChange(new RDFTriple((RDFSubjectNode)x, prop, type), ontology, true));
                    graph.onChange(evaluator, new RDFChange(new RDFTriple((RDFSubjectNode)y, prop, type), ontology, true));
                }
            });
        }
        private void buildInfClass() {
            addRule(new TranslatorRDF_Rule(0) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (y.getNodeType() == RDFNodeType.IRIReference) {
                        String iri = ((RDFIRIReference)y).getIRI().getHasValue();
                        if (iri.startsWith(VocRDF.rdf)) return;
                        if (iri.startsWith(VocRDF.rdfs)) return;
                        if (iri.startsWith(VocRDF.xsd)) return;
                        if (iri.startsWith(VocRDF.owl)) return;
                    }
                    RDFProperty prop = graph.getEntityNode(repository.getIRI(VocRDF.rdfType));
                    RDFNode type = graph.getEntityNode(repository.getIRI(VocRDF.owlClass));
                    graph.onChange(evaluator, new RDFChange(new RDFTriple((RDFSubjectNode)y, prop, type), ontology, true));
                }
            });
        }
        
        private void buildObjPropExp_InverseOf() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlInverseOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    expObjProperties.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectInverseOf value = new xowl.lang.owl2.ObjectInverseOf();
                            value.setInverse(getObjPropExpression(y));
                            return value;
                        }
                    });
                }
            });
        }
        
        private void buildDatarange_Intersection() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.rdfsDatatype),
                    getTriple(getVar("x"), VocRDF.owlIntersectionOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> intersected = toList_Unordered(y);
                    expDatarange.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataIntersectionOf value = new xowl.lang.owl2.DataIntersectionOf();
                            value.setDatarangeSeq(getDatarangeSequence(intersected));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildDatarange_Union() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.rdfsDatatype),
                    getTriple(getVar("x"), VocRDF.owlUnionOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> intersected = toList_Unordered(y);
                    expDatarange.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataUnionOf value = new xowl.lang.owl2.DataUnionOf();
                            value.setDatarangeSeq(getDatarangeSequence(intersected));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildDatarange_Complement() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.rdfsDatatype),
                    getTriple(getVar("x"), VocRDF.owlDatatypeComplementOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    expDatarange.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataComplementOf value = new xowl.lang.owl2.DataComplementOf();
                            value.setDatarange(getDatarange(y));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildDatarange_OneOf() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.rdfsDatatype),
                    getTriple(getVar("x"), VocRDF.owlOneOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> intersected = toList_Unordered(y);
                    expDatarange.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataOneOf value = new xowl.lang.owl2.DataOneOf();
                            value.setLiteralSeq(getLiteralSequence(intersected));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildDatarange_Restriction() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.rdfsDatatype),
                    getTriple(getVar("x"), VocRDF.owlOnDatatype, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlWithRestrictions, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    RDFNode z = getValue(bindings, "z");
                    final List<RDFNode> restrictions = toList_Unordered(z);
                    expDatarange.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DatatypeRestriction value = new xowl.lang.owl2.DatatypeRestriction();
                            value.setDatarange(getDatarange(y));
                            for (RDFNode restrictNode : restrictions) {
                                xowl.lang.owl2.FacetRestriction facet = new xowl.lang.owl2.FacetRestriction();
                                RDFTriple triple = getTriple((RDFSubjectNode)restrictNode);
                                facet.setConstrainingFacet(((RDFIRIReference)triple.getProperty()).getIRI());
                                facet.setConstrainingValue((xowl.lang.owl2.Literal)getLiteralExpression(triple.getObject()));
                                value.addFacetRestrictions(facet);
                            }
                            return value;
                        }
                    });
                }
            });
        }
        
        private void buildClassExp_Intersection() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlClass),
                    getTriple(getVar("x"), VocRDF.owlIntersectionOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> intersected = toList_Unordered(y);
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectIntersectionOf value = new xowl.lang.owl2.ObjectIntersectionOf();
                            value.setClassSeq(getClassSequence(intersected));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_Union() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlClass),
                    getTriple(getVar("x"), VocRDF.owlUnionOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> unified = toList_Unordered(y);
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectUnionOf value = new xowl.lang.owl2.ObjectUnionOf();
                            value.setClassSeq(getClassSequence(unified));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ComplementOf() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlClass),
                    getTriple(getVar("x"), VocRDF.owlComplementOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectComplementOf value = new xowl.lang.owl2.ObjectComplementOf();
                            value.setClasse(getClassExpression(y));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_OneOf() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlClass),
                    getTriple(getVar("x"), VocRDF.owlOneOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final List<RDFNode> unified = toList_Unordered(y);
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectOneOf value = new xowl.lang.owl2.ObjectOneOf();
                            value.setIndividualSeq(getIndividualSequence(unified));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjAllValuesFrom() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlAllValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectAllValuesFrom value = new xowl.lang.owl2.ObjectAllValuesFrom();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setClasse(getClassExpression(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjSomeValuesFrom() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlSomeValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectSomeValuesFrom value = new xowl.lang.owl2.ObjectSomeValuesFrom();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setClasse(getClassExpression(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjHasValue() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlHasValue, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectHasValue value = new xowl.lang.owl2.ObjectHasValue();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setIndividual(getIndividualExpression(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjHasSelf() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlHasSelf, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectHasSelf value = new xowl.lang.owl2.ObjectHasSelf();
                            value.setObjectProperty(getObjPropExpression(y));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjMinQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMinQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectMinCardinality value = new xowl.lang.owl2.ObjectMinCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setClasse(getClassExpression(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjMaxQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMaxQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectMaxCardinality value = new xowl.lang.owl2.ObjectMaxCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setClasse(getClassExpression(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjExactQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z")),
                    getTriple(getVar("y"), VocRDF.rdfType, VocRDF.owlObjectProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectExactCardinality value = new xowl.lang.owl2.ObjectExactCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setClasse(getClassExpression(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjMinCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMinCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectMinCardinality value = new xowl.lang.owl2.ObjectMinCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjMaxCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMaxCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectMaxCardinality value = new xowl.lang.owl2.ObjectMaxCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_ObjExactCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.ObjectExactCardinality value = new xowl.lang.owl2.ObjectExactCardinality();
                            value.setObjectProperty(getObjPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataHasValue() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlHasValue, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataHasValue value = new xowl.lang.owl2.DataHasValue();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setLiteral(getLiteralExpression(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataAllValuesFrom() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlAllValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataAllValuesFrom value = new xowl.lang.owl2.DataAllValuesFrom();
                            List<RDFNode> list = new ArrayList<RDFNode>();
                            list.add(y);
                            value.setDataPropertySeq(getDataPropSequence(list));
                            value.setDatarange(getDatarange(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataSomeValuesFrom() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlSomeValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataSomeValuesFrom value = new xowl.lang.owl2.DataSomeValuesFrom();
                            List<RDFNode> list = new ArrayList<RDFNode>();
                            list.add(y);
                            value.setDataPropertySeq(getDataPropSequence(list));
                            value.setDatarange(getDatarange(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataAllValuesFrom2() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperties, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlAllValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final List<RDFNode> list = toList_Unordered(y);
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataAllValuesFrom value = new xowl.lang.owl2.DataAllValuesFrom();
                            value.setDataPropertySeq(getDataPropSequence(list));
                            value.setDatarange(getDatarange(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataSomeValuesFrom2() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperties, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlSomeValuesFrom, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final List<RDFNode> list = toList_Unordered(y);
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataSomeValuesFrom value = new xowl.lang.owl2.DataSomeValuesFrom();
                            value.setDataPropertySeq(getDataPropSequence(list));
                            value.setDatarange(getDatarange(z));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataMinQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMinQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataMinCardinality value = new xowl.lang.owl2.DataMinCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setDatarange(getDatarange(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataMaxQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMaxQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataMaxCardinality value = new xowl.lang.owl2.DataMaxCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setDatarange(getDatarange(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataExactQualifiedCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlQualifiedCardinality, getVar("n")),
                    getTriple(getVar("x"), VocRDF.owlOnClass, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode z = getValue(bindings, "z");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataExactCardinality value = new xowl.lang.owl2.DataExactCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setDatarange(getDatarange(z));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataMinCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMinCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataMinCardinality value = new xowl.lang.owl2.DataMinCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataMaxCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlMaxCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataMaxCardinality value = new xowl.lang.owl2.DataMaxCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        private void buildClassExp_DataExactCard() {
            addRule(new TranslatorRDF_Rule(1) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlRestriction),
                    getTriple(getVar("x"), VocRDF.owlOnProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlCardinality, getVar("n"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    final RDFNode y = getValue(bindings, "y");
                    final RDFNode n = getValue(bindings, "n");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    expClasses.put(x, new ExpressionSolver() {
                        @Override public xowl.lang.owl2.Expression getExpression() {
                            xowl.lang.owl2.DataExactCardinality value = new xowl.lang.owl2.DataExactCardinality();
                            value.setDataProperty(getDataPropExpression(y));
                            value.setCardinality(getLiteralExpression(n));
                            return value;
                        }
                    });
                }
            });
        }
        
        private void buildAxiomSubClassOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("sub"), VocRDF.rdfsSubClassOf, getVar("super"))  
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode sup = getValue(bindings, "super");
                    RDFNode sub = getValue(bindings, "sub");
                    xowl.lang.owl2.SubClassOf axiom = new xowl.lang.owl2.SubClassOf();
                    axiom.setClasse(getClassExpression(sub));
                    axiom.setSuperClass(getClassExpression(sup));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomEquivalentClass() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlEquivalentClass, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.owlClass))
                        return;
                    if (!isOfType(c2, VocRDF.owlClass))
                        return;
                    xowl.lang.owl2.EquivalentClasses axiom = new xowl.lang.owl2.EquivalentClasses();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setClassSeq(getClassSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDisjointClasses() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlDisjointWith, getVar("c2"))  
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    xowl.lang.owl2.DisjointClasses axiom = new xowl.lang.owl2.DisjointClasses();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setClassSeq(getClassSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAllDisjointClasses() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlAllDisjointClasses),
                    getTriple(getVar("x"), VocRDF.owlMembers, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    xowl.lang.owl2.DisjointClasses axiom = new xowl.lang.owl2.DisjointClasses();
                    axiom.setClassSeq(getClassSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDisjointUnionOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlDisjointUnionOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    xowl.lang.owl2.DisjointUnion axiom = new xowl.lang.owl2.DisjointUnion();
                    axiom.setClasse(getClassExpression(x));
                    axiom.setClassSeq(getClassSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSubObjPropertyOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("sub"), VocRDF.rdfsSubPropertyOf, getVar("super"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode sup = getValue(bindings, "super");
                    RDFNode sub = getValue(bindings, "sub");
                    if (!isOfType(sub, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.SubObjectPropertyOf axiom = new xowl.lang.owl2.SubObjectPropertyOf();
                    axiom.setObjectProperty(getObjPropExpression(sub));
                    axiom.setSuperObjectProperty(getObjPropExpression(sup));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSubObjPropertyOf_Chain() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlPropertyChainAxiom, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    List<RDFNode> chain = toList_Ordered(getValue(bindings, "y"));
                    xowl.lang.owl2.SubObjectPropertyOf axiom = new xowl.lang.owl2.SubObjectPropertyOf();
                    axiom.setObjectPropertyChain(getObjPropSequence(chain));
                    axiom.setSuperObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomEquivalentObjProp() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlEquivalentProperty, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.owlObjectProperty))
                        return;
                    if (!isOfType(c2, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.EquivalentObjectProperties axiom = new xowl.lang.owl2.EquivalentObjectProperties();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setObjectPropertySeq(getObjPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDisjointObjProp() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlPropertyDisjointWith, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.owlObjectProperty))
                        return;
                    if (!isOfType(c2, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.DisjointObjectProperties axiom = new xowl.lang.owl2.DisjointObjectProperties();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setObjectPropertySeq(getObjPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAllDisjointObjProps() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlAllDisjointProperties),
                    getTriple(getVar("x"), VocRDF.owlMembers, getVar("y")),
                    getTriple(getVar("y"), VocRDF.rdfFirst, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    if (!isOfType(getValue(bindings, "z"), VocRDF.owlObjectProperty))
                        return;
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    xowl.lang.owl2.DisjointObjectProperties axiom = new xowl.lang.owl2.DisjointObjectProperties();
                    axiom.setObjectPropertySeq(getObjPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomObjPropDomain() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.ObjectPropertyDomain axiom = new xowl.lang.owl2.ObjectPropertyDomain();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axiom.setClasse(getClassExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomObjPropRange() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.ObjectPropertyRange axiom = new xowl.lang.owl2.ObjectPropertyRange();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axiom.setClasse(getClassExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomInverseOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlInverseOf, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(x, VocRDF.owlObjectProperty))
                        return;
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.InverseObjectProperties axiom = new xowl.lang.owl2.InverseObjectProperties();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axiom.setInverse(getObjPropExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomFunctionalObjectProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlFunctionalProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    if (!isOfType(x, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.FunctionalObjectProperty axiom = new xowl.lang.owl2.FunctionalObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomInverseFunctionalProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlInverseFunctionalProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.InverseFunctionalObjectProperty axiom = new xowl.lang.owl2.InverseFunctionalObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomReflexiveProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlReflexiveProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.ReflexiveObjectProperty axiom = new xowl.lang.owl2.ReflexiveObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomIrreflexiveProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlIrreflexiveProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.IrreflexiveObjectProperty axiom = new xowl.lang.owl2.IrreflexiveObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSymmetricProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlSymmetricProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.SymmetricObjectProperty axiom = new xowl.lang.owl2.SymmetricObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAsymmetricProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlAsymmetricProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.AsymmetricObjectProperty axiom = new xowl.lang.owl2.AsymmetricObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomTransitiveProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlTransitiveProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    xowl.lang.owl2.TransitiveObjectProperty axiom = new xowl.lang.owl2.TransitiveObjectProperty();
                    axiom.setObjectProperty(getObjPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSubDataPropertyOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("sub"), VocRDF.rdfsSubPropertyOf, getVar("super"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode sup = getValue(bindings, "super");
                    RDFNode sub = getValue(bindings, "sub");
                    if (!isOfType(sub, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.SubDataPropertyOf axiom = new xowl.lang.owl2.SubDataPropertyOf();
                    axiom.setDataProperty(getDataPropExpression(sub));
                    axiom.setSuperDataProperty(getDataPropExpression(sup));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomEquivalentDataProp() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlEquivalentProperty, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.owlDataProperty))
                        return;
                    if (!isOfType(c2, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.EquivalentDataProperties axiom = new xowl.lang.owl2.EquivalentDataProperties();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setDataPropertySeq(getDataPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDisjointDataProp() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlPropertyDisjointWith, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.owlDataProperty))
                        return;
                    if (!isOfType(c2, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.DisjointDataProperties axiom = new xowl.lang.owl2.DisjointDataProperties();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(c1);
                    list.add(c2);
                    axiom.setDataPropertySeq(getDataPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAllDisjointDataProps() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlAllDisjointProperties),
                    getTriple(getVar("x"), VocRDF.owlMembers, getVar("y")),
                    getTriple(getVar("y"), VocRDF.rdfFirst, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    if (!isOfType(getValue(bindings, "z"), VocRDF.owlDataProperty))
                        return;
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    xowl.lang.owl2.DisjointDataProperties axiom = new xowl.lang.owl2.DisjointDataProperties();
                    axiom.setDataPropertySeq(getDataPropSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDataPropDomain() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(x, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.DataPropertyDomain axiom = new xowl.lang.owl2.DataPropertyDomain();
                    axiom.setDataProperty(getDataPropExpression(x));
                    axiom.setClasse(getClassExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDataPropRange() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(x, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.DataPropertyRange axiom = new xowl.lang.owl2.DataPropertyRange();
                    axiom.setDataProperty(getDataPropExpression(x));
                    axiom.setDatarange(getDatarange(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomFunctionalDataProperty() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlFunctionalProperty)
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    if (!isOfType(x, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.FunctionalDataProperty axiom = new xowl.lang.owl2.FunctionalDataProperty();
                    axiom.setDataProperty(getDataPropExpression(x));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomEquivalentDatatype() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("c1"), VocRDF.owlEquivalentClass, getVar("c2"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode c1 = getValue(bindings, "c1");
                    RDFNode c2 = getValue(bindings, "c2");
                    if (!isOfType(c1, VocRDF.rdfsDatatype))
                        return;
                    if (!isOfType(c2, VocRDF.rdfsDatatype))
                        return;
                    xowl.lang.owl2.DatatypeDefinition axiom = new xowl.lang.owl2.DatatypeDefinition();
                    axiom.setDatatype(getDatarange(c1));
                    axiom.setDatarange(getDatarange(c2));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomHasKey() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlHasKey, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    List<RDFNode> objProps = new ArrayList<RDFNode>();
                    List<RDFNode> dataProps = new ArrayList<RDFNode>();
                    for (RDFNode elem : list)  {
                        if (isOfType((RDFSubjectNode)elem, VocRDF.owlObjectProperty))
                            objProps.add(elem);
                        else
                            dataProps.add(elem);
                    }
                    xowl.lang.owl2.HasKey axiom = new xowl.lang.owl2.HasKey();
                    axiom.setClasse(getClassExpression(x));
                    axiom.setObjectPropertySeq(getObjPropSequence(objProps));
                    axiom.setDataPropertySeq(getDataPropSequence(dataProps));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSameAs() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlSameAs, getVar("y"))  
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    xowl.lang.owl2.SameIndividual axiom = new xowl.lang.owl2.SameIndividual();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(x);
                    list.add(y);
                    axiom.setIndividualSeq(getIndividualSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDifferentFrom() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.owlDifferentFrom, getVar("y")),
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    xowl.lang.owl2.DifferentIndividuals axiom = new xowl.lang.owl2.DifferentIndividuals();
                    List<RDFNode> list = new ArrayList<RDFNode>();
                    list.add(x);
                    list.add(y);
                    axiom.setIndividualSeq(getIndividualSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAllDifferent() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlAllDifferent),
                    getTriple(getVar("x"), VocRDF.owlMembers, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    List<RDFNode> list = toList_Unordered(getValue(bindings, "y"));
                    xowl.lang.owl2.DifferentIndividuals axiom = new xowl.lang.owl2.DifferentIndividuals();
                    axiom.setIndividualSeq(getIndividualSequence(list));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomClassAssertion() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(y, VocRDF.owlClass))
                        return;
                    xowl.lang.owl2.ClassAssertion axiom = new xowl.lang.owl2.ClassAssertion();
                    axiom.setIndividual(getIndividualExpression(x));
                    axiom.setClasse(getClassExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomObjectPropertyAssertion() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), getVar("y"), getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlObjectProperty))
                        return;
                    xowl.lang.owl2.ObjectPropertyAssertion axiom = new xowl.lang.owl2.ObjectPropertyAssertion();
                    axiom.setIndividual(getIndividualExpression(x));
                    axiom.setObjectProperty(getObjPropExpression(y));
                    axiom.setValueIndividual(getIndividualExpression(z));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomDataPropertyAssertion() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), getVar("y"), getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    RDFNode z = getValue(bindings, "z");
                    if (!isOfType(y, VocRDF.owlDataProperty))
                        return;
                    xowl.lang.owl2.DataPropertyAssertion axiom = new xowl.lang.owl2.DataPropertyAssertion();
                    axiom.setIndividual(getIndividualExpression(x));
                    axiom.setDataProperty(getDataPropExpression(y));
                    axiom.setValueLiteral(getLiteralExpression(z));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomNegativeObjectPropertyAssertion() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlNegativePropertyAssertion),
                    getTriple(getVar("x"), VocRDF.owlSourceIndividual, getVar("w")),
                    getTriple(getVar("x"), VocRDF.owlAssertionProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlTargetIndividual, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode w = getValue(bindings, "w");
                    RDFNode y = getValue(bindings, "y");
                    RDFNode z = getValue(bindings, "z");
                    xowl.lang.owl2.ObjectPropertyAssertion axiom = new xowl.lang.owl2.ObjectPropertyAssertion();
                    axiom.setIndividual(getIndividualExpression(w));
                    axiom.setObjectProperty(getObjPropExpression(y));
                    axiom.setValueIndividual(getIndividualExpression(z));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomNegativeDataPropertyAssertion() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfType, VocRDF.owlNegativePropertyAssertion),
                    getTriple(getVar("x"), VocRDF.owlSourceIndividual, getVar("w")),
                    getTriple(getVar("x"), VocRDF.owlAssertionProperty, getVar("y")),
                    getTriple(getVar("x"), VocRDF.owlTargetValue, getVar("z"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode w = getValue(bindings, "w");
                    RDFNode y = getValue(bindings, "y");
                    RDFNode z = getValue(bindings, "z");
                    xowl.lang.owl2.DataPropertyAssertion axiom = new xowl.lang.owl2.DataPropertyAssertion();
                    axiom.setIndividual(getIndividualExpression(w));
                    axiom.setDataProperty(getDataPropExpression(y));
                    axiom.setValueLiteral(getLiteralExpression(z));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomSubAnnotPropertyOf() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("sub"), VocRDF.rdfsSubPropertyOf, getVar("super"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode sup = getValue(bindings, "super");
                    RDFNode sub = getValue(bindings, "sub");
                    if (!isOfType(sub, VocRDF.owlAnnotationProperty))
                        return;
                    xowl.lang.owl2.SubAnnotationPropertyOf axiom = new xowl.lang.owl2.SubAnnotationPropertyOf();
                    axiom.setAnnotProperty(getAnnotPropExpression(sub));
                    axiom.setSuperAnnotProperty(getAnnotPropExpression(sup));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAnnotPropDomain() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(x, VocRDF.owlAnnotationProperty))
                        return;
                    xowl.lang.owl2.AnnotationPropertyDomain axiom = new xowl.lang.owl2.AnnotationPropertyDomain();
                    axiom.setAnnotProperty(getAnnotPropExpression(x));
                    axiom.setAnnotDomain(getAnnotPropExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        private void buildAxiomAnnotPropRange() {
            addRule(new TranslatorRDF_Rule(2) {
                @Override public RDFTriple[] getPatterns() { return new RDFTriple[] {
                    getTriple(getVar("x"), VocRDF.rdfsDomain, getVar("y"))
                }; }
                @Override public void activate(Map<XOWLVariableNode, RDFNode> bindings) {
                    RDFNode x = getValue(bindings, "x");
                    RDFNode y = getValue(bindings, "y");
                    if (!isOfType(x, VocRDF.owlAnnotationProperty))
                        return;
                    xowl.lang.owl2.AnnotationPropertyRange axiom = new xowl.lang.owl2.AnnotationPropertyRange();
                    axiom.setAnnotProperty(getAnnotPropExpression(x));
                    axiom.setAnnotRange(getAnnotPropExpression(y));
                    axioms.add(axiom);
                }
            });
        }
        
        private List<RDFNode> toList_Ordered(RDFNode sequence) {
            List<RDFNode> elements = new ArrayList<RDFNode>();
            while (true) {
                if (sequence.getNodeType() == RDFNodeType.IRIReference) {
                    if (VocRDF.rdfNil.equals(((RDFIRIReference)sequence).getIRI().getHasValue()))
                        return elements;
                }
                List<RDFNode> values = getValues((RDFSubjectNode)sequence, VocRDF.rdfFirst);
                List<RDFNode> rests = getValues((RDFSubjectNode)sequence, VocRDF.rdfRest);
                elements.add(values.get(0));
                sequence = rests.get(0);
            }
        }
        
        private List<RDFNode> toList_Unordered(RDFNode sequence) {
            return toList_Ordered(sequence);
        }
        
        protected List<RDFNode> getValues(RDFSubjectNode subject, String property) {
            List<RDFNode> results = new ArrayList<RDFNode>();
            List<RDFTriple> triples = graph.getTriples(subject, repository.getIRI(property));
            if (triples == null)
                return results;
            for (RDFTriple triple : triples)
                results.add(triple.getObject());
            return results;
        }
        
        protected RDFTriple getTriple(RDFSubjectNode subject) {
            List<RDFTriple> triples = graph.getTriples(subject);
            return triples.get(0);
        }
        
        protected boolean isOfType(RDFNode subject, String type) {
            List<RDFNode> types = getValues((RDFSubjectNode)subject, VocRDF.rdfType);
            for (RDFNode value : types) {
                if (value.getNodeType() == RDFNodeType.IRIReference) {
                    String iri = ((RDFIRIReference)value).getIRI().getHasValue();
                    if (type.equals(iri))
                        return true;
                }
            }
            return false;
        }
    }
}
